﻿using System;

using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace Silvermoon.Controls
{
    /// <summary>
    /// Specifies margins for a control.
    /// </summary>
    public struct Margin
    {
        #region ctors

        public Margin(int size)
        {
            this.left = this.right = this.top = this.bottom = size;
        }

        public Margin(int? left, int? top, int? right, int? bottom)
        {
            this.left = left;
            this.top = top;
            this.right = right;
            this.bottom = bottom;
        }

        public Margin(Rectangle rect) : this(rect.Left, rect.Top, rect.Right, rect.Bottom) { }

        public override string ToString()
        {
            return string.Format("left: {0}, top: {1}, right: {2}, bottom: {3}", LeftZero, TopZero, RightZero, BottomZero);
        }

        #endregion
        #region fields

        private int? left, right, top, bottom;

        #endregion
        #region Properties

        public int? Left { get { return left; } set { left = value; } }
        public int? Right { get { return right; } set { right = value; } }
        public int? Top { get { return top; } set { top = value; } }
        public int? Bottom { get { return bottom; } set { bottom = value; } }

        public int TopZero { get { return top ?? 0; } }
        public int LeftZero { get { return left ?? 0; } }
        public int RightZero { get { return right ?? 0; } }
        public int BottomZero { get { return bottom ?? 0; } }
        public int Width { get { return LeftZero + RightZero; } }
        public int Height { get { return  TopZero + BottomZero; } }

        public bool IsEmpty
        {
            get
            {
                return Left == null && Right == null && Top == null && Bottom == null;
            }
        }

        public static readonly Margin Empty = new Margin();

        #endregion
        #region Methods

        public override int GetHashCode()
        {
            const int notAssigned = -99999;
            int a = Left ?? notAssigned;
            int b = Right ?? notAssigned;
            int c = Top ?? notAssigned;
            int d = Bottom ?? notAssigned;
            return (((a ^ ((c << 13) | (c >> 0x13))) ^ ((b << 0x1a) | (b >> 6))) ^ ((d << 7) | (d >> 0x19)));

        }

        public override bool Equals(object obj)
        {
            if (!(obj is Margin)) return false;

            Margin m = (Margin)obj;
            return m.left == left && m.right == right && m.top == top && m.bottom == Bottom;
        }


        public static bool operator ==(Margin a, Margin b)
        {
            return a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom;
        }

        public static bool operator !=(Margin a, Margin b)
        {
            return a.left != b.left || a.right != b.right || a.top != b.top || a.bottom != b.bottom;
        }


        #endregion

    }
}
